using System;
using System.Collections.Generic;
using System.Windows.Documents;

namespace com.bodurov.SilverlightControls.XmlCodeEditor.Extensions
{
    public static class Paragraph_Ext
    {
        public static string GetContent(this Paragraph paragraph)
        {
            return paragraph.Inlines.GetContent();
        }
        public static IEnumerable<Run> GetRuns(this Paragraph paragraph)
        {
            return paragraph.Inlines.GetRuns();
        }
        public static Run GetFirstRun(this Paragraph paragraph)
        {
            if (paragraph.Inlines.Count == 0) return null;
            var first = paragraph.Inlines[0] as Run;
            if (first != null || paragraph.Inlines.Count == 1) return first;
            for (var i = 1; i < paragraph.Inlines.Count; i++)
            {
                var curr = paragraph.Inlines[i] as Run;
                if (curr != null) return curr;
            }
            return null;
        }
        public static Paragraph GetPrevious(this Paragraph paragraph)
        {
            return GetNeighbour(paragraph, LogicalDirection.Backward, e => e.ElementStart);
        }
        public static Paragraph GetNext(this Paragraph paragraph)
        {
            return GetNeighbour(paragraph, LogicalDirection.Forward, e => e.ElementEnd);
        }
        private static Paragraph GetNeighbour(this Paragraph paragraph, LogicalDirection direction, Converter<TextElement, TextPointer> getPointer)
        {
            var sign = direction == LogicalDirection.Forward ? 1 : -1;
            var currentPointer = getPointer(paragraph);
            while (true)
            {
                currentPointer = currentPointer.GetPositionAtOffset(1 * sign, direction);
                if (currentPointer == null)// if no more pointers exist - there is no paragraph in that direction
                {
                    return null;
                }
                var element = currentPointer.Parent as TextElement;
                if (element == null) // if pointer points to no text element - there is no paragraph in that direction
                {
                    return null;
                }
                var candidate = element as Paragraph;
                if (candidate == null) // if the current element is not a paragraph - go to the next element in the same direction
                {
                    currentPointer = getPointer(element);
                    continue;
                }
                // the current element is paragraph - so return it
                return candidate;
            }
        }
        public static string GetPreviousParagraphContent(this Paragraph paragraph)
        {
            var previous = paragraph.GetPrevious();
            return previous == null ? null : previous.GetContent();
        }
        public static string GetNextParagraphContent(this Paragraph paragraph)
        {
            var next = paragraph.GetNext();
            return next == null ? null : next.GetContent();
        }
        public static Run GetPreviousParagraphLastRun(this Paragraph paragraph)
        {
            var previous = paragraph.GetPrevious();
            if (previous == null) return null;
            return previous.Inlines.GetLastRun();
        }
        public static string GetWhiteSpaceOnTheLeft(this Paragraph paragraph)
        {
            return paragraph.Inlines.GetWhiteSpaceOnTheLeft();
        }
    }
}